home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
C
/
LIB
/
DESK
/
CORE
/
Desk
/
h_doc
/
Save
< prev
next >
Wrap
Text File
|
1996-05-21
|
12KB
|
299 lines
/*
#### # # # #
# # # # # The FreeWare C library for
# # ## ### # # # # ### RISC OS machines
# # # # # # # # # # # ___________________________________
# # #### ### ## # # # #
# # # # # # # # # # Please refer to the accompanying
#### ### #### # # ##### # ### documentation for conditions of use
________________________________________________________________________
File: save.h
Author: Copyright © 1994 Julian Smith and Jason Howat
Version: 1.02 (18 Jun 1994)
Purpose: Automate handling of save-as windows
Mods: 13-Jun-1994 - JPS - Added filetype handling
18-Jun-1994 - JDH - See Save.c
*/
#ifndef __Desk_Save_h
#define __Desk_Save_h
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#ifndef __Desk_Event_h
#include "Desk.Event.h"
#endif
typedef Desk_bool (*Desk_save_filesaver)(char *f, void *ref);
/*
This type of function should save data to file given by 'f', using info
in 'ref'. It should return Desk_bool_TRUE if it was successful. 'ref' is the (void
*) originally passed to Desk_Save_InitSaveWindowHandler
*/
typedef int (*Desk_save_ramsaver)(
Desk_task_handle sourcetask, /* our task handle */
void *ref,
Desk_task_handle desttask,
void *destbuffer,
unsigned int buffersize,
int progress /* how many bytes have been transfered so far */
);
/*
This type of function should Desk_Wimp_TransferBlock data. Note that you can
do this using multiple Desk_Wimp_TransferBlock's if this is more convinient.
Should return the total number of bytes transfered into 'destbuffer' -
if less than buffersize, then transfer has finished. If <0, error has
occurred. 'ref' is the (void *) originally passed to
Desk_Save_InitSaveWindowHandler
*/
typedef enum
{
Desk_save_SAVEOK = 0,
Desk_save_RECEIVERFAILED,
Desk_save_FILESAVERFAILED,
Desk_save_RAMSAVERFAILED
} Desk_save_result;
typedef void (*Desk_save_resulthandler)(Desk_save_result result, void *ref);
/* Called after any attempt to save. */
typedef struct
{
Desk_window_handle window; /* Window that the save icons are in */
union
{
unsigned int value;
struct
{
unsigned int Desk_is_menu : 1; /* Savewindow is part of menu */
unsigned int Desk_is_save_window : 1; /* Close window after save? */
unsigned int Desk_we_are_dragging : 1; /* Are we dragging file icon? */
unsigned int Desk_quit_after_save : 1; /* Click/drag was with Select */
unsigned int Desk_release_after : 1; /* Release all handlers when */
/* the window/menu is closed? */
unsigned int padding : 27;
} data;
} flags;
Desk_icon_handle dragsprite;
Desk_icon_handle okbutton;
Desk_icon_handle cancelbutton;
Desk_icon_handle filenameicon;
Desk_save_filesaver filesaver;
Desk_save_ramsaver ramsaver;
Desk_save_resulthandler resulthandler;
size_t estimatedsize;
int filetype;
void *ref;
int Desk_ram_progress; /* Num of bytes ram-transfered. */
unsigned int Desk_last_message_ref; /* So we know which incoming */
/* messages are replies to us */
} Desk_save_saveblock;
/*
This struct contains all the info needed to deal with saving using the
RISC OS data transfer protocol.
It is used internally by the Desk_Save_* functions - you shouldn't need to
use it normally. It is included here because Desk_Save_InitSaveWindowHandler
returns a pointer to it, so that you can call
Desk_Save_ReleaseSaveWindowHandler if you are using RO2 and have to detect
menu closing manually, and also you might want to change the field 'ref'
if the user presses a 'Selection' button in the save window (you might
also want to change 'filesaver' and 'ramsaver' in this case).
Also, you could change 'Desk_is_menu' if a menu-leaf savewindow changes into
to a free-standing savewindow (this will only work if you have
.flags.data.Desk_release_after = Desk_bool_FALSE - the saveblock wil be free-ed and all
Desk_Event_ handlers released when the menu is closed otherwise.
fn 'filesaver' is called when the data needs to be saved to a file.
fn 'ramsaver' is called when the data needs to be RAM transfered.
'ref' is passed to file/ramsaver - it should enable these functions to
save the right piece of data.
You can change the following things after you have called
Desk_Save_InitSaveWindowHandler:
Desk_is_menu, Desk_is_save_window, filesaver, ramsaver, resulthandler,
estimatedsize, ref.
Don't change any of the icon or window handles, as these will have been
used with Desk_Event_Claim, so if you change them, when Desk_Save_* calls
Desk_Event_Release, DeskLib will complain.
Also, don't change any other fields (there is no reason to anyway) as
these are used internally and are assumed to be const.
*/
Desk_save_saveblock *Desk_Save_InitSaveWindowHandler(
Desk_window_handle window, /* handle of the window to deal with */
Desk_bool Desk_is_menu, /* is this window part of a menu? */
/* if Desk_bool_TRUE Desk_Save_* will close it after */
/* 'Select'-saves */
Desk_bool Desk_is_save_window, /* is this window just a save window? */
/* if Desk_bool_TRUE Desk_Save_* will close it after */
/* 'Select'-saves */
Desk_bool Desk_release_after, /* release all Desk_Save_ handlers when */
/* window/menu is closed? */
Desk_icon_handle dragsprite, /* handle of the dragable file-icon */
Desk_icon_handle okbutton, /* handle of 'OK' or 'Save' button */
Desk_icon_handle cancelbutton, /* handle of the 'Cancel' button */
Desk_icon_handle filenameicon, /* handle of the writable fname icon */
Desk_save_filesaver filesaver, /* fn which saves data to a file */
Desk_save_ramsaver ramsaver, /* fn which does Desk_Wimp_TransferBlocks */
Desk_save_resulthandler resulthandler, /* fn to report success of save to */
size_t estimatedsize, /* size of data (estimate) */
int filetype,
void *ref /* ref passed to all saver functions */
);
/*
To implement RISC OS saving, call this function - it does all the
message handling needed, and calls 'filesaver' or 'ramsaver' when
needed, passing 'ref' to them so that they know what needs saving.
'ismenu' should be Desk_bool_TRUE if 'window' is part of a menu tree, and Desk_bool_FALSE if
'window' is normal window. This is used to know when to stop handling
the save, e.g. when menu is closed, or when save-window is closed.
Things you need to do:
Create a conventional save-window with icons for Save, Cancel, and
dragging, and an *indirected* text icon for the filename. (e.g. put this
in a 'Templates' file). The filename icon *must* be indirected.
Put a default file/leafname in to the filename icon.
Make the dragable icon be whatever file-icon is appropriate
Write a function which can save the data to a file. *Required*
Write a function which can Desk_Wimp_TransferBlock the data. *Optional*
Write a function to be called with result of any save *Optional*
Create a reference, 'ref', to the data so that the saver functions know
what data to save.
Call Desk_Save_InitSaveWindowHandler You can do this anytime - e.g. just
before/after you create a menu that includes the save window, when you
open the save box in response to (for e.g.) a F3 keypress, or when you
receive a Desk_message_MENUWARNING which heralds the opening of your
save-window.
YOU are responsible for opening the savewindow and dealing with menu
handling. All Desk_Save_* does is handle the sprite-drgging, button pressing
and data transfer protocol which originate in the save window.
Then, when the user tries to save the data, the only thing which you get
to know about is that either your 'filesaver' or 'ramsaver' is called,
with the 'ref' you originally passed to Desk_Save_InitSaveWindowHandler. If a
save is attempted, 'resulthandler' will be called, with the
success/failure of the save.
Thats it.
Notes:
The 'filenameicon' may be altered by Desk_Save_InitSaveWindowHandler - it
replaces the first control chr by ASCII 0, as this works with standard C
functions, and some template text icons seem to be terminated by ASCII
13.
if you use 'Desk_release_after = Desk_bool_FALSE', the Desk_Event_ handlers will still be in
place after the window/menu has closed. This is so you can keep a single
window for all saves, and register it with Desk_Save_ just once when your
application starts up. If your application deals with different pieces
of data, you'll have to update the 'ref' field in the Desk_Save_saveblock
returned by Desk_Save_InitSaveWindowHandler each time the window is opened.
Desk_Save_* registers a handler for when the save window is closed, which
Desk_Event_Release's all of the Desk_Save_* handlers for drag/click/message
handling etc. This means you can have a save window with a close icon as
well as/instead of the 'cancel' icon, and makes the whole thing a bit
more robust.
You can miss out any of the icons in the window by using a negative icon
handle. This will prevent any Desk_Event_Claim's for the icon.
If 'ramsaver' == NULL, then 'filesaver' will always be used. If
'resulthandler' == NULL, a default handler will be used, which will do
an 'Desk_Error_Report' if a save fails.
If 'resulthandler' != NULL, it will be called after any attempt to save
the data, with 'ref' and one of the following flags:
Desk_save_SAVEOK = 0 receiver signals the save went OK
Desk_save_SAVERECEIVERFAILED receiver didn't signal it has received the data
Desk_save_SAVESAVERFAILED your 'filesaver' function signalled an error
Desk_save_SAVERAMFAILED your 'ramsaver' function signalled an error
This is so that your app doesn't go away thinking data has been saved
when it hasn't. Note that your saver functions will not be aware of any
problem in the second case, where the receiver fails to load the scrap
file.
If you want to implement a 'Selection' button in the save window, you
should register a separate handler for Desk_event_CLICK on the 'Selection'
button in the save window, and when it is pressed, modify the saveblock
previously returned by Desk_Save_InitSaveWindowHandler, so that
Desk_save_saveblock.ref points to the selction data. You could also change
the writable icon contents and the 'file/ramsave' functions etc etc.
*/
void Desk_Save_ReleaseSaveHandlers(Desk_save_saveblock *saveblock);
/*
You shouldn't need this normally because menu/window closing is detected
by SaveBoxHandler, 'cos it detects Desk_message_MENUSDELEATED and
Desk_event_CLOSE. NB, in RO2, there is no Desk_message_MENUSDELEATED, so you will
have to call this function when you next open a menu, or something...
Also, if you want to close a free-standing (i.e. not in a menu)
save-window when <Escape> is pressed, you will need this function.
*/
void Desk_Save_SetFiletype(Desk_save_saveblock *saveblock, int filetype);
/*
Sets the sprite in the savewindow to be "Desk_file_..." and also alters the
saveblock so that the filetype is used whenever date is saved to the
filer or another application.
NB this function changes the dragsprite icon is an *undirected* sprite-
-only icon. If it was previously an indirected icon, the pointer to the
indirected data is lost forever!
*/
#ifdef __cplusplus
}
#endif
#endif